using System.Collections;
using SharpGraphT.Event;
using SharpGraphT.Sharp.Sharp.Util;

namespace SharpGraphT.Traverse;

public abstract class AbstractGraphIterator<TV, TE> : IGraphIterator<TV, TE>
    where TE : class, new() {
    protected readonly IGraph<TV, TE> graph;
    protected bool crossComponentTraversal;

    protected AbstractGraphIterator(IGraph<TV, TE> graph) {
        crossComponentTraversal = true;
        this.graph = Objects.RequireNonNull(graph, "graph must not be null");
    }

    public IGraph<TV, TE> Graph => graph;

    public void SetCrossComponentTraversal(bool crossComponentTraversal) =>
        this.crossComponentTraversal = crossComponentTraversal;

    public bool IsCrossComponentTraversal => crossComponentTraversal;

    public abstract bool MoveNext();

    public abstract void Reset();

    public abstract TV Current { get; }

    object IEnumerator.Current => Current;

    public abstract void Dispose();

    public abstract event EventHandler<ConnectedComponentTraversalEventArgs>
        ConnectedComponentFinished;

    public abstract event EventHandler<ConnectedComponentTraversalEventArgs>
        ConnectedComponentStarted;

    public abstract event EventHandler<EdgeTraversalEventArgs<TE>>
        EdgeTraversed;

    public abstract event EventHandler<VertexTraversalEventArgs<TV>>
        VertexTraversed;

    public abstract event EventHandler<VertexTraversalEventArgs<TV>>
        VertexFinished;
}